home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / SDDOS.ASM < prev    next >
Assembly Source File  |  1988-01-13  |  62KB  |  1,811 lines

  1.  
  2. CODE SEGMENT
  3.  
  4.       Org    0100
  5. Main:
  6.       Jmp    Install
  7.  
  8. ;---------------------------------------------------------------------------;
  9. ;                                                                           ;
  10. ;     Data Areas, Constants, Etc.                                           ;
  11. ;                                                                           ;
  12. ;---------------------------------------------------------------------------;
  13.  
  14. Version      Db      CR,'Switch Directory - DOS 1.0',CR,LF
  15. Copyright    Db      'Copyright (c) 1987, 1988 by Stephen M. Falatko',CR,LF
  16. FakeEOF      Db      26
  17.  
  18. Errlvl       Db      0                       ;DOS return code
  19.  
  20. ;
  21. ;  These are flags set by the command line processing
  22. ;
  23. ;
  24.  
  25. RootFlag     Db      0                  ; signal indicating default to root (0)
  26. CDFlag       Db      0                  ; signal of specific path (1)
  27. OneDeepFlag  Db      0                  ; search only current dir (1)
  28.  
  29. ;
  30. ;  This flag is set to indicate that a subdirectory has been found (ie if its
  31. ;  0 at the end then we did not find the subdirectory)
  32. ;
  33.  
  34. Done_Flag    Db      0                  ; found subdir during search
  35.  
  36. ;
  37. ;  If this flag is set then help is available if ? is entered on the
  38. ;  command line
  39. ;
  40.  
  41. HelpFlag     Db      1
  42.  
  43. ;
  44. ;  If this flag is set then we can use the internal stack feature
  45. ;
  46.  
  47. StackFlag    Db      1
  48. StackAddress Dw      ProgramEndH
  49.  
  50. ;
  51. ;  The Stack_Pointer points to the internal stack path.  This is initialized
  52. ;  to 0 and changes depending on user input.
  53. ;
  54.  
  55. Stack_Pointer Db     0
  56.  
  57. InternalStackMsg        Db CR,LF,'Internal Stack:',CR,LF,CR,LF,Stopper
  58. Numbers                 Db ' 0 - ',0
  59.                         Db ' 1 - ',0
  60.                         Db ' 2 - ',0
  61.                         Db ' 3 - ',0
  62.                         Db ' 4 - ',0
  63.                         Db ' 5 - ',0
  64.                         Db ' 6 - ',0
  65.                         Db ' 7 - ',0
  66.                         Db ' 8 - ',0
  67.                         Db ' 9 - ',0
  68.  
  69. CR_LF         Db     CR,LF,Stopper
  70.  
  71. ;
  72. ;  These variables hold the systems Ctrl-Break address so we can restore
  73. ;  it when we exit
  74. ;
  75.  
  76. CtrlBrkOff   Dw      0
  77. CtrlBrkSeg   Dw      0
  78.  
  79. ;
  80. ;  Here we will store the desired subdirectory (and drive if selected)
  81. ;  as well as the original path and drive
  82. ;
  83.  
  84. Sub_Dir      Db      63 Dup (0)              ; The sub dir we want to change to
  85.  
  86. ScratchDirStart Db 'x:\'                     ; This is a scratch area for the
  87. ScratchDir      Db 63 Dup (0)                ; GetDir function
  88.  
  89. OD   LABEL  Word
  90.  
  91. OrigDr       Db      'x:'                    ; Original drive
  92. OrigDir      Db      '\',63 Dup (0)          ; and path
  93.  
  94. RootDir      Db      'x:\',0                 ; To get vol label
  95.  
  96. Count        Dw      0                       ; Number of args on command line
  97.  
  98. ;
  99. ;  These variables are used by the search routine
  100. ;
  101.  
  102. DtaPointer   Dw      DtaAreaBegin            ; Pointer to our DTA area
  103. Direction    Db      0                       ; Flag to indicate search subdirs
  104.                                              ; of the current dir or not
  105. BackOneDir   Db      '..',0                  ; Asciiz 'filename' to backup
  106.                                              ; one directory
  107. SearchAsciiZ Db      '*.*',0                 ; Search filename
  108.  
  109.  
  110.  
  111.  
  112. Old_INT_21 LABEL Dword                       ; Storage for previous INT 21
  113.  
  114. INT_21Off       Dw ?
  115. INT_21Seg       Dw ?
  116.  
  117. FirstTime?      Db 1                         ; flag to signal first pass
  118.                                              ; through INT 21 handler
  119. Command_Addr    Dw ?                         ; segment address of command.com
  120.  
  121. ;
  122. ; We want to save the callers DS:DX in the INT 21 handler
  123. ;
  124.  
  125. Callers_DS      Dw ?                         ; caller's data segment
  126. Callers_DX      Dw ?                         ; caller's dx register
  127.  
  128. CReturn         Db 0D
  129.  
  130. CR_LFString     Db 0D,0A,'$'
  131.  
  132. ;
  133. ; Command is the string that we look for at the DOS prompt.  It must
  134. ; be 8 characters long with the empty spaces blanks.
  135. ;
  136.  
  137. Command         Db 'SD      '
  138.  
  139. ;
  140. ;     Error messages
  141. ;
  142.  
  143. NoHelp         Db  CR,LF,'ERROR - Installed without help',CR,LF,Stopper
  144. NoStack        Db  CR,LF,'ERROR - Installed without Stack feature',CR,LF,Stopper
  145.  
  146. ErrorMsgs      Db  CR,LF,'Illegal drive specifier - must be A to z',CR,LF,Stopper
  147.                Db  CR,LF,'Maximum of 64 characters on command line',CR,LF,Stopper
  148.                Db  CR,LF,'Illegal character on command line       ',CR,LF,Stopper
  149.                Db  CR,LF,'Currently in root directory             ',CR,LF,Stopper
  150.                Db  CR,LF,'Command line contains an invalid path   ',CR,LF,Stopper
  151.                Db  CR,LF,'Subdirectory Not Found                  ',CR,LF,Stopper
  152.                Db  CR,LF,'Selected stack entry is empty           ',CR,LF,Stopper
  153.  
  154.  
  155. New_INT_21:
  156.  
  157.         PUSH    ES,DS,BP,SI,DI,AX,BX,CX,DX
  158.  
  159. ;
  160. ;  Is this a request for buffered input?  If not go to next INT 21.
  161. ;
  162.  
  163.         CMP     AH,0A                   ; Function 0A (hex) ?
  164.         IF NE JMP Exit_INT_21           ; If not then let's leave ....
  165.  
  166. ;
  167. ;  Let's get the length of the original caller's buffer DS:DX points
  168. ;  to caller's buffer with the first byte holding the maximum length.
  169. ;
  170.  
  171.         MOV     BX,DX
  172.         DS MOV  CL,B [BX]
  173.  
  174. ;
  175. ;  Save DS and DX of calling program and make DS equal to CS
  176. ;
  177.  
  178.         PUSH    DS                      ; Store caller's DS
  179.         MOV     DS,CS                   ; Change DS to CS
  180.  
  181.         POP     Callers_DS              ; Pop caller's DS to Old_DS
  182.  
  183.         PUSH    DX                      ; Store caller's DX
  184.         POP     Callers_DX
  185.  
  186. ;
  187. ;  We will use our command line for a buffer so copy the max length of the
  188. ;  callers buffer to the first position of the new buffer
  189. ;
  190.         MOV     BX,080                  ; Point BX to the PSP command line
  191.         MOV     B [BX],CL               ; Store the buffer length in the
  192.                                         ; first position
  193.  
  194. ;
  195. ;  Point the BP to the SP
  196. ;
  197.  
  198.         MOV     BP,SP
  199.  
  200. ;
  201. ;  Now, if it's the first time through here then COMMAND.COM is calling and we
  202. ;  save the segment address off the stack.  By doing this we can later
  203. ;  verify if a caller is COMMAND.COM or not.
  204. ;
  205.  
  206.         TEST    FirstTime?              ; If not the first time go on
  207.         JZ      Not_First_Time
  208.  
  209.         SS MOV  BX,W [BP+4]             ; Get COMMAND.COM's segment address
  210.         MOV     Command_Addr,BX         ; Save it
  211.  
  212.         MOV     FirstTime?,0            ; Clear flag
  213.         JMP     Intercept
  214.  
  215. ;
  216. ;  If this is not the first time through then we want to see if the caller
  217. ;  is COMMAND.COM or not.
  218. ;
  219.  
  220. Not_First_Time:
  221.  
  222.         SS MOV  BX,W [BP+4]             ; Get caller's segment address
  223.         CMP     BX,Command_Addr         ; Compare it with COMMAND.COM'S
  224.         IF NE JMP Exit_INT_21           ; If its not the same go to next INT 21
  225.  
  226. ;
  227. ;  Now we know that the caller is DOS so let's get the user input into our
  228. ;  own temporary buffer so we can check it against our commands.
  229. ;
  230. ;  We begin by setting up a DOS call for buffered input.
  231. ;
  232.  
  233.  
  234. Intercept:
  235.  
  236.         MOV     DX,080                  ; Point DS:DX to our PSP
  237.         MOV     AH,0A                   ; DOS function call 0A hex
  238.         PUSHF                           ; Simulate DOS interrupt
  239.         CALL Old_INT_21
  240.  
  241. ;
  242. ;  We have performed the caller's INT 21 call, now we must see if the
  243. ;  entered command is one of ours or whether we must pass it on to COMMAND.COM
  244. ;
  245.  
  246.         PUSHF                           ; First save the flags
  247.         CLD                             ; and clear the direction flag
  248.  
  249. ;
  250. ;  To simplify our comparison we will use DOS function 29 hex, parse filename,
  251. ;  to strip leading blanks and capitalize the input string.  We will store the
  252. ;  result in the PSP FCB #1 location
  253. ;
  254.  
  255.         MOV     ES,CS                   ; Make ES equal CS
  256.         MOV     SI,082                  ; The source string starts in the PSP
  257.         MOV     DI,05C